package com.santalu.emptyview;

import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.render.BlendMode;
import ohos.agp.transition.TransitionScheduler;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextTool;
import ohos.app.Context;

import static com.santalu.emptyview.EmptyViewBuilder.State.CONTENT;

/**
 * EmptyView
 *
 * @author santalu
 * @since 2017/08/09
 */

public class EmptyView extends DependentLayout {
    private EmptyViewBuilder builder;
    private DependentLayout container;
    private RoundProgressBar progressBar;
    private Image imageView;
    private Text titleView;
    private Text textView;
    private Button button;

    public EmptyView(Context context) {
        this(context, null, null);
    }

    public EmptyView(Context context, AttrSet attrs) {
        this(context, attrs, null);
    }

    public EmptyView(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        builder = new EmptyViewBuilder(this, attrs);
        Component rootComponent = LayoutScatter.getInstance(context)
                .parse(ResourceTable.Layout_empty_view_ohos, null, false);
        initComponent(rootComponent);
        addComponent(rootComponent);
    }

    private void initComponent(Component rootComponent) {
        if (rootComponent.findComponentById(ResourceTable.Id_empty_layout) instanceof DependentLayout) {
            container = (DependentLayout) rootComponent.findComponentById(ResourceTable.Id_empty_layout);
        }
        if (rootComponent.findComponentById(ResourceTable.Id_empty_icon) instanceof Image) {
            imageView = (Image) rootComponent.findComponentById(ResourceTable.Id_empty_icon);
        }
        if (rootComponent.findComponentById(ResourceTable.Id_empty_text) instanceof Text) {
            textView = (Text) rootComponent.findComponentById(ResourceTable.Id_empty_text);
        }
        if (rootComponent.findComponentById(ResourceTable.Id_empty_title) instanceof Text) {
            titleView = (Text) rootComponent.findComponentById(ResourceTable.Id_empty_title);
        }
        if (rootComponent.findComponentById(ResourceTable.Id_empty_button) instanceof Button) {
            button = (Button) rootComponent.findComponentById(ResourceTable.Id_empty_button);
        }
        if (rootComponent.findComponentById(ResourceTable.Id_empty_progress_bar) instanceof RoundProgressBar) {
            progressBar = (RoundProgressBar) rootComponent.findComponentById(ResourceTable.Id_empty_progress_bar);
        }
    }

    @Override
    public void addComponent(Component childComponent) {
        super.addComponent(childComponent);
        if (childComponent.getVisibility() == VISIBLE) {
            builder.include(childComponent);
        }
    }

    @Override
    public void setClickedListener(ClickedListener listener) {
        builder.setOnClickListener(listener);
    }

    /**
     * builder
     *
     * @return EmptyViewBuilder
     */
    public EmptyViewBuilder builder() {
        return builder;
    }

    /**
     * content
     *
     * @return EmptyViewBuilder
     */
    public EmptyViewBuilder content() {
        return builder.setState(CONTENT);
    }

    /**
     * loading
     *
     * @return EmptyViewBuilder
     */
    public EmptyViewBuilder loading() {
        return builder.setState(EmptyViewBuilder.State.LOADING);
    }

    /**
     * empty
     *
     * @return EmptyViewBuilder
     */
    public EmptyViewBuilder empty() {
        return builder.setState(EmptyViewBuilder.State.EMPTY);
    }

    /**
     * error
     *
     * @return EmptyViewBuilder
     */
    public EmptyViewBuilder error() {
        return builder.setState(EmptyViewBuilder.State.ERROR);
    }

    /**
     * error
     *
     * @param t Throwable
     * @return EmptyViewBuilder
     */
    public EmptyViewBuilder error(Throwable t) {
        Error error = Error.get(t);
        return error(error);
    }

    /**
     * error
     *
     * @param error Error
     * @return EmptyViewBuilder
     */
    public EmptyViewBuilder error(Error error) {
        return error()
                .setErrorTitle(error.getTitle(getContext()))
                .setErrorText(error.getMessage(getContext()));
    }

    /**
     * state
     *
     * @return EmptyViewBuilder
     */
    public EmptyViewBuilder.State state() {
        return builder.state;
    }

    /**
     * showContent
     */
    public void showContent() {
        content().show();
    }

    /**
     * showLoading
     */
    public void showLoading() {
        loading().show();
    }

    /**
     * showEmpty
     */
    public void showEmpty() {
        empty().show();
    }

    /**
     * showError
     */
    public void showError() {
        error().show();
    }

    void show() {
        // start animation
        if (builder.transition != null) {
            TransitionScheduler transitionScheduler = new TransitionScheduler();
            transitionScheduler.setTransition(builder.transition);
            if (builder.state == CONTENT) {
                transitionScheduler.startNewRootTransition((ComponentContainer) progressBar
                        .getComponentParent(), (ComponentContainer) builder.children.get(0));
            } else {
                transitionScheduler.startNewRootTransition((ComponentContainer) progressBar
                        .getComponentParent(), (ComponentContainer) textView.getComponentParent());
            }
        }

        switch (builder.state) {
            case CONTENT:
                container.setVisibility(HIDE);
                progressBar.setVisibility(HIDE);
                imageView.setVisibility(HIDE);
                titleView.setVisibility(HIDE);
                textView.setVisibility(HIDE);
                button.setVisibility(HIDE);
                setChildVisibility(VISIBLE);
                setContainer(Color.TRANSPARENT.getValue());
                break;
            case EMPTY:
                container.setVisibility(VISIBLE);
                progressBar.setVisibility(HIDE);
                imageView.setVisibility(VISIBLE);
                titleView.setVisibility(VISIBLE);
                textView.setVisibility(VISIBLE);
                button.setVisibility(VISIBLE);
                setChildVisibility(HIDE);
                setContainer(builder.emptyBackgroundColor);
                setIcon(builder.emptyDrawable, builder.emptyDrawableTint);
                setTitle(builder.emptyTitle, builder.emptyTitleTextColor);
                setText(builder.emptyText, builder.emptyTextColor);
                setButton(builder.emptyButtonText, builder.emptyButtonTextColor,
                        builder.emptyButtonBackgroundColor);
                break;
            case ERROR:
                container.setVisibility(VISIBLE);
                progressBar.setVisibility(HIDE);
                imageView.setVisibility(VISIBLE);
                titleView.setVisibility(VISIBLE);
                textView.setVisibility(VISIBLE);
                button.setVisibility(VISIBLE);
                setChildVisibility(HIDE);
                setContainer(builder.errorBackgroundColor);
                setIcon(builder.errorDrawable, builder.errorDrawableTint);
                setTitle(builder.errorTitle, builder.errorTitleTextColor);
                setText(builder.errorText, builder.errorTextColor);
                setButton(builder.errorButtonText, builder.errorButtonTextColor,
                        builder.errorButtonBackgroundColor);
                break;
            case LOADING:
                container.setVisibility(VISIBLE);
                progressBar.setVisibility(VISIBLE);
                imageView.setVisibility(HIDE);
                titleView.setVisibility(VISIBLE);
                textView.setVisibility(VISIBLE);
                button.setVisibility(HIDE);
                setChildVisibility(HIDE);
                setContainer(builder.loadingBackgroundColor);
                setProgressBar(builder.loadingType, builder.loadingDrawableTint);
                setIcon(builder.loadingDrawable, builder.loadingDrawableTint);
                setTitle(builder.loadingTitle, builder.loadingTitleTextColor);
                setText(builder.loadingText, builder.loadingTextColor);
                break;
        }
    }

    private void setChildVisibility(int visibility) {
        for (Component view : builder.children) {
            view.setVisibility(visibility);
        }
    }

    private void setContainer(int backgroundColor) {
        container.setAlignment(builder.gravity);
        // 创建背景元素
        ShapeElement shapeElement = new ShapeElement();
        // 设置颜色
        shapeElement.setRgbColor(RgbColor.fromArgbInt(backgroundColor));

        container.setBackground(shapeElement);
    }

    private void setProgressBar(EmptyViewBuilder.LoadingType style, int tint) {
        if (progressBar.getVisibility() != VISIBLE) {
            return;
        }
        if (style == EmptyViewBuilder.LoadingType.NONE) {
            progressBar.setVisibility(HIDE);
            return;
        }
        progressBar.setVisibility(VISIBLE);
        if (tint != 0) {
            Element drawable = progressBar.getProgressElement();
            if (drawable != null) {
                getTintElement(drawable, tint);
            }
        }
    }

    /**
     * 更改Element颜色
     *
     * @param element  Element
     * @param intColor 颜色
     * @return Element
     */
    public static Element getTintElement(Element element, int intColor) {
        int[] colors = new int[]{intColor, intColor};
        int[][] states = new int[2][];
        states[0] = new int[]{1};
        states[1] = new int[]{-1};
        element.setStateColorList(states, colors);
        element.setStateColorMode(BlendMode.SRC_ATOP);
        return element;
    }

    private void setIcon(Element drawable, int tint) {
        if (imageView.getVisibility() != VISIBLE) {
            return;
        }
        if (drawable == null) {
            imageView.setVisibility(HIDE);
            return;
        }
        imageView.setVisibility(VISIBLE);
        imageView.setImageElement(getTintElement(drawable, tint));
    }

    private void setTitle(String text, int textColor) {
        if (titleView.getVisibility() != VISIBLE) {
            return;
        }
        if (TextTool.isNullOrEmpty(text)) {
            titleView.setVisibility(HIDE);
            return;
        }
        titleView.setVisibility(VISIBLE);
        titleView.setText(text);
        titleView.setTextColor(new Color(textColor));
        titleView.setFont(builder.font);
        if (builder.titleTextSize != 0) {
            EmptyUtils.setTextSize(titleView, builder.titleTextSize);
        }
    }

    private void setText(String text, int textColor) {
        if (textView.getVisibility() != VISIBLE) {
            return;
        }
        if (TextTool.isNullOrEmpty(text)) {
            textView.setVisibility(HIDE);
            return;
        }
        textView.setVisibility(VISIBLE);
        textView.setText(text);
        textView.setTextColor(new Color(textColor));
        textView.setFont(builder.font);
        if (builder.textSize != 0) {
            EmptyUtils.setTextSize(textView, builder.textSize);
        }
    }

    private void setButton(String text, int textColor, int backgroundColor) {
        if (button.getVisibility() != VISIBLE) {
            return;
        }
        if (TextTool.isNullOrEmpty(text)) {
            button.setVisibility(HIDE);
            return;
        }
        button.setVisibility(VISIBLE);
        button.setText(text);
        button.setTextColor(new Color(textColor));
        button.setFont(builder.font);
        if (builder.buttonTextSize != 0) {
            EmptyUtils.setTextSize(button, builder.buttonTextSize);
        }
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(RgbColor.fromArgbInt(backgroundColor));
        button.setBackground(shapeElement);
        button.setClickedListener(builder.onClickListener);
    }
}
